package com.icinfo.cloud.provider.punish.config.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.icinfo.cloud.provider.common.constant.Constant;
import com.icinfo.cloud.provider.common.exception.BusinessException;
import com.icinfo.cloud.provider.punish.config.dto.CompareDiscretionDto;
import com.icinfo.cloud.provider.punish.config.dto.CompareSingleDiscretionDto;
import com.icinfo.cloud.provider.punish.config.enums.DiscretionRuleTypeEnum;
import com.icinfo.cloud.provider.punish.config.mapper.ConfigOrgRegulatoryDiscretionRuleHisMapper;
import com.icinfo.cloud.provider.punish.config.model.ConfigOrgRegulatoryDiscretionRuleHis;
import com.icinfo.cloud.provider.punish.config.service.IConfigOrgRegulatoryDiscretionRuleHisService;
import com.icinfo.cloud.provider.punish.config.vo.DiscretionHisVo;
import com.icinfo.framework.core.service.support.MyBatisServiceSupport;
import com.icinfo.framework.mybatis.mapper.entity.Example;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Function;
import java.util.stream.Collectors;


/**
 * 自由裁量相关
 * @author HKxxx
 * @date 2024/1/31 15:26
 */
@Slf4j
@Service
@Transactional(rollbackFor = Exception.class)
public class ConfigOrgRegulatoryDiscretionRuleHisServiceImpl extends MyBatisServiceSupport implements IConfigOrgRegulatoryDiscretionRuleHisService {

    @Resource
    private ConfigOrgRegulatoryDiscretionRuleHisMapper configOrgRegulatoryDiscretionRuleHisMapper;


    @Override
    public void insertBatch(List<ConfigOrgRegulatoryDiscretionRuleHis> hisList){
        if (CollUtil.isEmpty(hisList)){
            return;
        }
        configOrgRegulatoryDiscretionRuleHisMapper.insertBatch(hisList);
    }

    @Override
    public Map<String, DiscretionHisVo> getDiscretionHisByRuleHisIds(List<String> hisIds) {
        if (CollUtil.isEmpty(hisIds)){
            return Collections.emptyMap();
        }
        Example example = new Example(ConfigOrgRegulatoryDiscretionRuleHis.class);
        example.createCriteria().andIn("ruleHisId", hisIds);
        List<ConfigOrgRegulatoryDiscretionRuleHis> ruleHis = configOrgRegulatoryDiscretionRuleHisMapper.selectByExample(example);
        if (CollUtil.isEmpty(ruleHis)){
            return Collections.emptyMap();
        }

        return ruleHis.stream().map(DiscretionHisVo::convertDiscretionHisVo).collect(Collectors.toMap(DiscretionHisVo::getRuleHisId, Function.identity()));
    }

    @Override
    public DiscretionHisVo getDiscretionHisByRuleHisId(String hisId) {
        if (StrUtil.isEmpty(hisId)){
            return new DiscretionHisVo();
        }
        ConfigOrgRegulatoryDiscretionRuleHis query = new ConfigOrgRegulatoryDiscretionRuleHis();
        query.setRuleHisId(hisId);
        ConfigOrgRegulatoryDiscretionRuleHis his = configOrgRegulatoryDiscretionRuleHisMapper.selectOne(query);
        return DiscretionHisVo.convertDiscretionHisVo(his);
    }

    @Override
    public void verifyDiscretionAmount(CompareDiscretionDto compareDiscretionDto) {
        if (CollUtil.isEmpty(compareDiscretionDto.getDiscretionRuleHisIds())) {
            return;
        }
        if (CollUtil.isEmpty(compareDiscretionDto.getPunishInfoMap())) {
            return;
        }
        Example example = new Example(ConfigOrgRegulatoryDiscretionRuleHis.class);
        example.createCriteria().andIn("ruleHisId", compareDiscretionDto.getDiscretionRuleHisIds());
        List<ConfigOrgRegulatoryDiscretionRuleHis> ruleHis = configOrgRegulatoryDiscretionRuleHisMapper.selectByExample(example);
        if (compareDiscretionDto.getDiscretionRuleHisIds().size() != ruleHis.size()){
            throw new BusinessException("缺少相关自由裁量信息");
        }
        ruleHis.forEach(his -> compareAmount(compareDiscretionDto.getPunishInfoMap().get(his.getRuleHisId()), his));
    }

    @Override
    public void verifySingleDiscretionAmount(CompareSingleDiscretionDto dto) {
        if (StrUtil.isEmpty(dto.getHisId())) {
            return;
        }
        if (StrUtil.isEmpty(dto.getAmount())) {
            return;
        }
        ConfigOrgRegulatoryDiscretionRuleHis query = new ConfigOrgRegulatoryDiscretionRuleHis();
        query.setRuleHisId(dto.getHisId());
        ConfigOrgRegulatoryDiscretionRuleHis his = configOrgRegulatoryDiscretionRuleHisMapper.selectOne(query);
        if (Objects.isNull(his)){
            throw new BusinessException("无相关自由裁量信息");
        }
        compareAmount(dto.getAmount(), his);
    }

    /**
     * 比较处罚金额
     */
    private void compareAmount(String amountStr, ConfigOrgRegulatoryDiscretionRuleHis his) {
        // 如果类型为空说明没有选择罚款项，则不需要校验
        if (Objects.isNull(his.getRuleType())) {
            return;
        }
        String e = "根据裁量基准文件，请输入%s~%s元之间";
        BigDecimal amount = new BigDecimal(amountStr);
        // 固定 处罚金额与固定金额不相等 不满足
        if (DiscretionRuleTypeEnum.FIX.getCode().equals(his.getRuleType()) && amount.compareTo(his.getFixAmount()) != Constant.INTEGER_0) {
            throw new BusinessException(String.format(e, his.getFixAmount(), his.getFixAmount()));
        }
        // 区间 处罚金额不在裁量区间内 不满足
        if (DiscretionRuleTypeEnum.RANGE.getCode().equals(his.getRuleType())
                && (amount.compareTo(his.getLowerLimitAmount()) < 0 || amount.compareTo(his.getUpperLimitAmount()) > 0)) {
            throw new BusinessException(String.format(e, his.getLowerLimitAmount(), his.getUpperLimitAmount()));
        }
    }




}
